package com.spzx.channel.service.impl;

import com.alibaba.fastjson2.JSON;
import com.spzx.channel.domain.vo.ItemVO;
import com.spzx.channel.domain.vo.SkuPriceVO;
import com.spzx.channel.domain.vo.SpecValueVO;
import com.spzx.channel.service.ItemService;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.core.utils.bean.BeanUtils;
import com.spzx.common.redis.cache.SpzxCache;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.RemoteSkuStockService;
import com.spzx.product.domain.*;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service
public class ItemServiceImpl implements ItemService {

    @Resource
    RemoteProductService remoteProductService;
    @Resource
    RemoteSkuStockService remoteSkuStockService;

    @Resource
    RedisTemplate redisTemplate;

    //业务层，需要查询前端需要的数据
    //前端需要的数据创建ItemVo映射
    //业务只需要查询ItemVo需要的数据即可，无需查询数据库
    //@Cacheable(value = "spzx:channel:cache",key = "'item:'#skuId")//value和key链接起来，表示缓存的键，key中可以使用springEl表达式获取形参
    //上面的缓存key为：spzx：channel:cache::item:1     1是skuId的值
    @SpzxCache(cacheKeyPrefix = "spzx:channel:cache:" , lockKeyPrefix = "spzx:channel:lock:",
            isCacheNull = true)
    @Override
    public ItemVO selectItemBySkuId(Long skuId) {



        ItemVO itemVO = new ItemVO();
        //1、根据skuId查询sku表中的数据
        //远程调用内部接口 需要在请求头中配置 from-source = inner的字符串
        // 解决： 通过feign客户端的 请求拦截器 全局配置！！
        R<ProductSku> skuR = remoteProductService.getSkuBySkuId(skuId);
        if (skuR.getCode() != 200) {
            throw new ServiceException("商品数据不存在！！");
        }
        ProductSku sku = skuR.getData();
        itemVO.setProductSku(sku);

        //封装价格数据
        SkuPriceVO skuPriceVO = new SkuPriceVO();
        skuPriceVO.setSkuId(skuId);
        skuPriceVO.setMarketPrice(skuR.getData().getMarketPrice());
        skuPriceVO.setSalePrice(skuR.getData().getSalePrice());

        itemVO.setSkuPrice(skuPriceVO);
        //2、根据skuId查询sku_stock中的库存数据
        //spzx-product需要提供远程调用接口1：根据skuId查询库存数据
        R<SkuStock> skuStockR = remoteSkuStockService.gettSkuStock(skuId);
        if (skuStockR.getCode() != 200) {
            throw new ServiceException("商品的库存数据异常");
        }
        SkuStock skuStock = skuStockR.getData();
        SkuStockVo skuStockVo = new SkuStockVo();
       /*
        skuStockVo.setSkuId(skuStock.getSkuId());
        skuStockVo.setSaleNum(skuStock.getSaleNum());
        skuStockVo.setAvailableNum(skuStock.getAvailableNum());
        */

        BeanUtils.copyProperties(skuStock, skuStockVo);//将skuStock对象的相同名称类型的属性拷贝给 skuStockVo对象
        itemVO.setSkuStockVo(skuStockVo);

        //3、根据1查询到的sku的productId查询product数据
        Long productId = sku.getProductId();
        //spzx-product需要提供远程调用接口2：根据productId查询product详情
        R<Product> productR = remoteProductService.getSpu(productId);
        if (productR.getCode() != 200) {
            throw new ServiceException("商品数据异常");
        }
        Product product = productR.getData();
        itemVO.setProduct(product);
        List<String> sliderUrls = StringUtils.isEmpty(product.getSliderUrls()) ? null : Arrays.asList(product.getSliderUrls().split(","));

        //轮播图
        itemVO.setSliderUrlList(sliderUrls);
        String specValue = product.getSpecValue();
        //将specvalue json 数组 转为specValueVo对象的 集合
        List<SpecValueVO> specValueVOS = JSON.parseArray(specValue, SpecValueVO.class);
        //product的规格值
        itemVO.setSpecValueList(specValueVOS);

        //4、根据1查询到的sku的productId查询product_details表 详情图列表
        //spzx-product需要提供远程调用接口3： 根据productId查询productDetails详情图列表数据
        R<ProductDetails> productDetailsR = remoteProductService.getDetails(productId);

        if (productDetailsR.getCode() != 200) {
            ProductDetails productDetails = productDetailsR.getData();
            String imageUrls = productDetails.getImageUrls();

            List<String> detailsimagesUrls = StringUtils.isEmpty(imageUrls)?null:Arrays.asList(imageUrls.split(","));
            itemVO.setDetailsImageUrlList(detailsimagesUrls);
        }

        //5、根据1查询到的sku的productId查询 sku表spu下所有的sku列表
        // spzx-product需要提供远程调用接口4：根据productId查询它所有的sku列表
        R<List<ProductSku>> skusR = remoteProductService.getSkus(productId);

        if(skusR.getCode()!=200){
            throw new ServiceException(skusR.getMsg());
        }
        List<ProductSku> skus = skusR.getData();
        Map<String,String> map= new HashMap<>();
        skus.forEach(productSku -> {
            map.put(productSku.getSkuSpec(),productSku.getId().toString());
        });

        itemVO.setSkuSpecValueMap(map);


        return itemVO;
    }

}
